﻿using System.Reflection;

using BodaNetCommunications.Utilities.Attributes;
using BodaNetCommunications.Utilities.ComTypes;
using BodaNetCommunications.Utilities.Results;

namespace BodaNetCommunications.Cores
{
    public class CommServiceFactory
    {
        /// <summary>
        /// 根据不通的协议去获取对应的服务
        /// </summary>
        /// <param name="protoclType">协议类型</param>
        /// <param name="connectionOptions">连接参数</param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public static BodaResult<ICommService> CreateService(ProtocolType? protoclType)
        {
            BodaResult<ICommService> bodaResult = new BodaResult<ICommService>();
            if(protoclType==null)
            {
                bodaResult.IsSuccess = false;
                bodaResult.Message = $"ProtoclType为空";
                return bodaResult;
            }
            // 反射获取标注指定协议的类型
            var types = Assembly.GetExecutingAssembly().GetTypes()
                    .Where(m => m.GetCustomAttribute<ProtocolTypeAttribute>() != null
                    && protoclType == m.GetCustomAttribute<ProtocolTypeAttribute>()?.ProtoclType);

            if (types == null || types.Count() > 1)
            {
                bodaResult.IsSuccess = false;
                bodaResult.Message = $"未能获取到协议为{protoclType}的Type，或者获取到多个相同的协议服务";
                return bodaResult;
            }

            ICommService? commService = null;
            // 反射获取协议的服务，并构造服务
            try
            {
                commService = Activator.CreateInstance(types.First()) as ICommService;
                if (commService == null)
                {
                    bodaResult.IsSuccess = false;
                    bodaResult.Message = $"反射未能获取到协议为{protoclType}的接口对象";
                    return bodaResult;
                }
            }
            catch (Exception ex)
            {
                bodaResult.IsSuccess = false;
                bodaResult.Message = $"反射未能获取到协议为{protoclType}的接口对象出错:{ex.Message}";
                return bodaResult;
            }

            bodaResult.IsSuccess = true;
            bodaResult.Content = commService;
            return bodaResult;
        }
    }
}
